/*
    SlideScript - minimalistic top-down scripting language.
    (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2)

    View README file supplied with this software for more details
*/


#include "inc/deps.h"
#include "inc/lexer.h"
#include "inc/util.h"

time_t current_time;

void syn_error(char *message)
{
    printf("%s\n", message);
    exit(1);
}

long fsize (FILE *in)
{
    long pos, length;
    pos = ftell(in);
    fseek(in, 0L, SEEK_END);
    length = ftell(in);
    fseek(in, pos, SEEK_SET);
    return length;
}

void syn_warn(char *message)
{
    printf("%s\n", message);
}

char *strip_nl (char *string)
{
    int n = strlen (string);

    if ((n-- > 0) && (string [n] == '\n'))
    {
        string [n] = NULLBYTE;
        return string;
    }
    else
    {
        /* no newline found, return the original string */
        return string;
    }
}

// Check if a file exists, return code
int file_exists(char *path) {
    struct stat   buffer;   
    return (stat (path, &buffer) == 0);
}

int is_dir(char *path)
{
    struct stat buffer;

    stat(path, &buffer);

    // Check for file existence
    if (S_ISDIR(buffer.st_mode))
        return 1;

    return 0;
}

// mkpath function for mkdir and mkfile
int mkpath(char* file_path, mode_t mode)
{
    assert(file_path && *file_path);
    for (char* p = strchr(file_path + 1, '/'); p; p = strchr(p + 1, '/')) 
    {
        *p = '\0';
        if (mkdir(file_path, mode) == -1) 
        {
            if (errno != EEXIST) 
            {
                *p = '/';
                return -1;
            }
        }
        *p = '/';
    }
    return 0;
}

char *ss_concat(char *str1, char *str2)
{
    char *dymem = qmalloc(QM_SS, (strlen(str1)+strlen(str2)) + 5);
    sprintf(dymem, "%s, %s", str1, str2);
    return dymem;
}

void parse_args(int argc, char** argv)
{
	/* -h flag given, show help */
	if(argc == 2 && strncmp("-h", argv[1], 2) == 0) 
	{
		printf("SlideScript - simple top-down scripting language for the average user\n"
		"Arguments:\n\n"
		"-v\t Display version number\n"
		"-h\t Display this help page\n"
		"Usage: %s <filename>\n", argv[0]);
		exit(EXIT_SUCCESS);
	} 
	/* -v flag given, show version */
	else if(argc == 2 && strncmp("-v", argv[1], 2) == 0) 
	{
		printf("SlideScript %s, Chris Dorman (cddo@riseup.net), 2022\n", VERSION);
		exit(EXIT_SUCCESS);
	}
	
}

char *ss_time()
{
    time(&current_time);

    return ctime(&current_time);
}

void gen_random_string(char *s, const int len) {
    static const char alphanum[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
    time_t tvar;
    srand((unsigned) time(&tvar));

    for (int ii = 0; ii < len; ++ii) {
        s[ii] = alphanum[rand() % (sizeof(alphanum) - 1)];
    }

    s[len] = 0;
}

// Removes extension from filename for compression
char *remove_extension(char *string)
{
    char *ret_string;
    char *lastExt;
    if (string == NULL) return (char *)NULL;
    if ((ret_string = malloc (strlen (string) + 1)) == NULL) return (char *)NULL;
    strcpy (ret_string, string);
    lastExt = strrchr (ret_string, '.');
    if (lastExt != NULL)
        *lastExt = '\0';
    return ret_string;
}

int check_for_var(char *string)
{
    if(strchr(string, '=') != NULL)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

char **line_to_args(char *line)
{
    int bufsize = MAXPATHLENGTH+1, position = 0;
    char **tokens = calloc(bufsize, sizeof(char*));
    char *token, **tokens_backup;

    if (!tokens) {
        fprintf(stderr, "cdsh: allocation error\n");
        exit(EXIT_FAILURE);
    }

    token = strtok(line, " ");
    while (token != NULL) {
        tokens[position] = strip_nl(token);
        position++;

        if (position >= bufsize) {
            bufsize += MAXPATHLENGTH;
            tokens_backup = tokens;
            tokens = realloc(tokens, bufsize * sizeof(char*));
            if (!tokens) {
		        free(tokens_backup);
                fprintf(stderr, "cdsh: allocation error\n");
                exit(EXIT_FAILURE);
            }
        }

        token = strtok(NULL, " ");
    }
    tokens[position] = NULL;
    return tokens;
}

int ss_exec(char **args)
{
    pid_t pid;
    int status;

    pid = fork();
    if (pid == 0) {
        // Child process
        if (execvp(args[0], args) == -1) {
            printf("ss:warn:failed to create child process\n");
        }

        return 1;

    } else if (pid < 0) {
            // Error forking
	        perror("cdsh");
        } else {
            // Parent process
            do {
                waitpid(pid, &status, WUNTRACED);
            } while (!WIFEXITED(status) && !WIFSIGNALED(status));
    }

    return 0;
}
